package com.pickgliss.ui
{
	import com.pickgliss.instance.IManualSize;
	import com.pickgliss.toplevel.StageReferance;
	import com.pickgliss.ui.core.Component;
	import com.pickgliss.ui.core.Disposeable;
	import com.pickgliss.ui.core.SpriteLayer;
	import com.pickgliss.ui.core.UISpriteLayer;
	import com.pickgliss.utils.Directions;
	import com.pickgliss.utils.DisplayUtils;
	import com.pickgliss.utils.ObjectUtils;
	
	import flash.display.DisplayObject;
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	public class LayerManager
	{
		private var _stageTopLayer:SpriteLayer;
		private var _stageDynamicLayer:SpriteLayer;
		private var _stageBottomLayer:SpriteLayer;
		private var _gameTopLayer:SpriteLayer;
		private var _gameDynamicLayer:SpriteLayer;
		private var _gameUILayer:SpriteLayer;
		private var _gameBaseLayer:SpriteLayer;
		private var _gameBottomLayer:SpriteLayer;
		private var _gameMenuLayer:SpriteLayer;
		
		public static const STAGE_BOTTOM_LAYER:int = 8;
		public static const STAGE_TOP_LAYER:int = 0;
		public static const STAGE_DYANMIC_LAYER:int = 1;
		public static const GAME_TOP_LAYER:int = 2;
		public static const GAME_DYNAMIC_LAYER:int = 3;
		public static const GAME_UI_LAYER:int = 4;
		public static const GAME_BASE_LAYER:int = 5;
		/**
		 * 游戏中底层
		 */
		public static const GAME_BOTTOM_LAYER:int = 6;
		public static const GAME_MENU_LAYER:int = 7;
		/**
		 * 没有蒙版
		 */
		public static const NONE_BLOCKGOUND:int = 0;
		/**
		 * 黑色蒙版
		 */
		public static const BLCAK_BLOCKGOUND:int = 1;
		/**
		 * 白色蒙版
		 */
		public static const ALPHA_BLOCKGOUND:int = 2;
		
		public var mutiContainer:Component;
		
		public function LayerManager()
		{
		}
		
		private static var _instance:LayerManager;
		public static function get Instance():LayerManager
		{
			if(_instance == null)
			{
				_instance = new LayerManager();
			}
			return _instance;
		}
		
		public function setup(stage:Stage):void
		{
			_stageTopLayer = new SpriteLayer();
			_stageDynamicLayer = new SpriteLayer();
			_stageBottomLayer = new SpriteLayer( true );
			_gameTopLayer = new SpriteLayer();
			_gameDynamicLayer = new SpriteLayer();
			_gameMenuLayer = new SpriteLayer();
			_gameUILayer = new UISpriteLayer();
			_gameBaseLayer = new SpriteLayer();
			_gameBottomLayer = new SpriteLayer();
			
			
//			stage.addChild(_gameBottomLayer);
			stage.addChild(_stageBottomLayer);
			
			
			stage.addChild(_stageDynamicLayer);
			stage.addChild(_stageTopLayer);
			
			_gameDynamicLayer.autoClickTotop = true;
			
			_stageBottomLayer.addChild(_gameBottomLayer);
			_stageBottomLayer.addChild(_gameBaseLayer);
			_stageBottomLayer.addChild(_gameUILayer);
			_stageBottomLayer.addChild(_gameDynamicLayer);
			_stageBottomLayer.addChild(_gameMenuLayer);
			_stageBottomLayer.addChild(_gameTopLayer);		
			
			mutiContainer = new Component();
			
			StageReferance.stage.addEventListener(MouseEvent.MOUSE_DOWN,__stageMouseDown);
		}
		
		private function __stageMouseDown(e:MouseEvent):void
		{
			var length:uint = _gameMenuLayer.numChildren;
			var remove_arr:Array = [];
			for (var i:int = 0; i < length; i++)
			{
				var child:DisplayObject = _gameMenuLayer.getChildAt(i);
//				var rect:Rectangle = child.getRect(StageReferance.stage);
				if(!child.hitTestPoint(e.stageX,e.stageY,true))
					remove_arr.push(child);
			}
			for (var j:int = 0; j < remove_arr.length; j++)
			{
				var element:Disposeable = remove_arr[j] as Disposeable;
				if(element) element.dispose();
			}
		}
		
		public function clearGameMenuLayer():void
		{
			cleanSprite(_gameMenuLayer);
		}
		public function getLayerByType(type:int):SpriteLayer
		{
			switch(type)
			{
				case STAGE_TOP_LAYER:
					return _stageTopLayer;
					break;
				case STAGE_DYANMIC_LAYER:
					return _stageDynamicLayer;
					break;
				case GAME_TOP_LAYER:
					return _gameTopLayer;
					break;
				case GAME_DYNAMIC_LAYER:
					return _gameDynamicLayer;
					break;
				case GAME_BASE_LAYER:
					return _gameBaseLayer;
					break;
				case GAME_BOTTOM_LAYER:
					return _gameBottomLayer;
					break;
				
				case GAME_UI_LAYER:
					return _gameUILayer;
					break;
				
				case STAGE_BOTTOM_LAYER:
					return _stageBottomLayer;
					break;
				case GAME_MENU_LAYER:
					ObjectUtils.disposeAllChildren(_gameMenuLayer);
					return _gameMenuLayer;
					break;
			}
			return null;
		}
		
		
		private var _settingMap:Dictionary = new Dictionary;
		public function get settingMap():Dictionary
		{
			return _settingMap;
		}
		
		public function addToSpecial(source:DisplayObject,type:int,center:Boolean = false,isAutoCenter:Boolean=false,direction:int = -1,offsetX:Number=0,offsetY:Number=0,blockBackgound:int = NONE_BLOCKGOUND,constraintCenter:Boolean=false):void
		{
			if(!source)return;
			var container:SpriteLayer = getLayerByType(type);
			_settingMap[source]=isAutoCenter;
			var visibleSize:Rectangle
			if(source is IManualSize)
			{
				visibleSize = (source as IManualSize).viewRectangle;
			}
			else
			{
				var sw:Number = ObjectUtils.getObjectWidth(source);
				var sh:Number = ObjectUtils.getObjectHeight(source);
				visibleSize = (constraintCenter ? DisplayUtils.getVisibleSize(source) : source.getBounds(StageReferance.stage));
			}
			var stageWidth:Number = StageReferance.gameStageWidth;
			var stageHeight:Number = StageReferance.gameStageHeight;
			source.y = (stageHeight - visibleSize.height)/2 +  offsetY;
			if(direction == Directions.DIRECTION_L)//靠左偏移
			{
				source.x = stageWidth - visibleSize.width +  offsetX;
			}
			else if(direction == 0)//居中偏移
			{
				source.x = (stageWidth - visibleSize.width)/2 +  offsetX;
			}
			container.addTolayer(source,blockBackgound);
		}
		
		private var _settingMap2:Dictionary = new Dictionary();
		public function addToLayer(source:DisplayObject,type:int,center:Boolean = false,isAutoCenter:Boolean=false,blockBackgound:int = NONE_BLOCKGOUND,containerType:int=0,constraintCenter:Boolean=false):void
		{
			var container:SpriteLayer = getLayerByType(type);
			_settingMap[source] = isAutoCenter;
			if(center) {
				source.addEventListener(Event.ADDED_TO_STAGE, __onAddedToStage);
				_settingMap2[source] = constraintCenter;
			}
			if(type == GAME_MENU_LAYER)
			{
				if(source.x + source.width > StageReferance.gameStageWidth)
					source.x = StageReferance.gameStageWidth - source.width;
				if(source.y + source.height > StageReferance.gameStageHeight)
					source.y = StageReferance.gameStageHeight - source.height;
				StageReferance.stage.focus = source as InteractiveObject;
			}
			container.addTolayer(source,blockBackgound,containerType);
		}
		
		private var _sourceList:Array = new Array();
		private function __onAddedToStage(event:Event):void 
		{
			var source:DisplayObject = event.currentTarget as DisplayObject;
			_sourceList.push(source);
			source.removeEventListener(Event.ADDED_TO_STAGE, __onAddedToStage);
			StageReferance.stage.removeEventListener(Event.RESIZE, __onStageResize);
			if(StageReferance.stage.stageWidth == 0 && StageReferance.stage.stageHeight == 0) 
			{
				StageReferance.stage.addEventListener(Event.RESIZE, __onStageResize);
			} 
			else 
			{
				centerToStage(source, _settingMap2[source]);
				_sourceList.pop();
				delete _settingMap2[source];
			}
		}
		private function __onStageResize(event:Event):void 
		{
			if(StageReferance.stage.stageWidth > 0 && StageReferance.stage.stageHeight > 0) 
			{
				StageReferance.stage.removeEventListener(Event.RESIZE, __onStageResize);
				for (var i:int = 0;i<_sourceList.length ;i++)
				{
					centerToStage(_sourceList[i], _settingMap2[_sourceList[i]]);
				}
				_sourceList = [];
				_settingMap2 = null;
				_settingMap2 = new Dictionary();
			}
		}
		private function centerToStage(source:DisplayObject, constraintCenter:Boolean=false):void 
		{
			var visibleSize:Rectangle;
			if(source is IManualSize)
			{
				visibleSize = (source as IManualSize).viewRectangle;
			} 
			else
			{
				var sw:Number = ObjectUtils.getObjectWidth(source);
				var sh:Number = ObjectUtils.getObjectHeight(source);
				visibleSize = constraintCenter ? DisplayUtils.getVisibleSize(source) : source.getBounds(StageReferance.stage);
			}
			source.x = (StageReferance.gameStageWidth - visibleSize.width) / 2;
			source.y = (StageReferance.gameStageHeight - visibleSize.height) / 2;
		}
		
		public function addTolayerRelated(source1:DisplayObject,source2:DisplayObject,type:int,center:Boolean = true,isAutoCenter:Boolean=false,blockBackgound:int = NONE_BLOCKGOUND):void
		{
			var container:SpriteLayer = getLayerByType(type);
			var centerPosX:int = (StageReferance.gameStageWidth - source1.width) / 2;
			source1.x = centerPosX - source2.width / 2;
			source2.x = source1.x + source1.width + 35;
			source2.y = source1.y;
			container.addTolayer(source1,blockBackgound);
			container.addTolayer(source2,blockBackgound);
		}
		public function clearnStageDynamic():void
		{
			cleanSprite(_stageDynamicLayer);
		}
		
		public function clearnGameDynamic():void
		{
			StageReferance.stage.focus = null;
			cleanSprite(_gameDynamicLayer);
		}
		
		public function cleanGameTop():void
		{
			cleanSprite(_gameTopLayer);
		}
		
		private function cleanSprite(target:Sprite):void
		{
			while(target.numChildren > 0)
			{
				var child:DisplayObject = target.getChildAt(0);
				ObjectUtils.disposeObject(child);
			}
		}
	}
}